﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.IO;
using System.Runtime.Serialization;
using System.Runtime.Serialization.Formatters.Binary;

using Microsoft.WindowsAPICodePack.Shell;

namespace My_TV_Manager.Model
{
    [Serializable()]

    public class Season : ISerializable, IComparable
    {
        #region Private Data

        private int number;
        private List<Episode> episodes;
        private DateTime lastModified;

        #endregion

        #region Properties

        public int Number { get { return number; } }
        public List<Episode> Episodes { get { return episodes; } }
        public int Size { get { return episodes.Count; } }
        public DateTime LastModified { get { return lastModified; } }

        #endregion

        #region Constructors

        // Default constructor for testing
        public Season()
        {
            number = 0;
            episodes = new List<Episode>();
            lastModified = DateTime.Now;
        }

        // Constructor to create a new season
        public Season(int number, List<Episode> episodes)
        {
            this.number = number;
            this.episodes = episodes;
            lastModified = DateTime.Now;
        }

        // Constructor to create a new season at a specific time
        public Season(int number, List<Episode> episodes, DateTime lastModified)
        {
            this.number = number;
            this.episodes = episodes;
            this.lastModified = lastModified;
        }

        // Constructor which parses a directory
        public Season(string directory)
        {
            int loc = directory.LastIndexOf('\\') + 1;
            string temp = directory.Substring(loc);
            number = int.Parse(temp.Substring(7, temp.Length - 7));

            ShellFileSystemFolder sFolder = ShellFileSystemFolder.FromFolderPath(directory);
            lastModified = (DateTime)sFolder.Properties.System.DateModified.Value;

            string[] dir = Directory.GetFiles(directory);

            episodes = new List<Episode>();
            foreach (string d in dir)
            {
                episodes.Add(new Episode(d));
            }
        }

        #endregion

        #region Functions

        // Recursive print
        public void Print()
        {
            Console.Out.WriteLine("\tSeason " + number);
            foreach (Episode episode in episodes)
            {
                episode.Print();
            }
        }

        // Add an episode to the list
        public bool Add(Episode episode)
        {
            // Reject episodes with invalid data
            if (episode.SeasonNumber <= 0 ||
                episode.EpisodeNumber <= 0)
            {
                return false;
            }

            episodes.Add(episode);
            return true;
        }

        // Sort the episodes
        public void Sort()
        {
            episodes.Sort();
        }

        #endregion

        #region ISerializable Members

        // Deserialization constructor
        public Season(SerializationInfo info, StreamingContext context)
        {
            number = info.GetInt32("Number");
            lastModified = info.GetDateTime("LastModified");
            episodes = (List<Episode>)info.GetValue("Episodes", typeof(List<Episode>));
        }

        // Implemented for serialization
        public void GetObjectData(SerializationInfo info, StreamingContext context)
        {
            info.AddValue("Number", number);
            info.AddValue("LastModified", lastModified);
            info.AddValue("Episodes", episodes, typeof(List<Episode>));
        }

        #endregion

        #region IComparable Members

        public int CompareTo(object obj)
        {
            if (obj is Season)
            {
                Season s = (Season)obj;
                return number.CompareTo(s.Number);
            }
            else
            {
                throw new ArgumentException("Object is not of type Season");
            }
        }

        #endregion
    }
}
